package com.rrd.dw.mr.gzip.bhzx;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer.Context;

import com.rrd.dw.utils.DateUtil;
import com.rrd.dw.utils.MD5Util;

/**
 * 处理当前已经结清的数据
 * 按每次还款记录计算
 * @author liubaoxin
 *
 */
public class BHZXPayoffUtils {
	public static final String CRT_FLAG = "\001";
    public static final Pattern CRT_PATTERN = Pattern.compile(CRT_FLAG);
    private static NullWritable key_null = NullWritable.get();
	private static Text val_Text = new Text();
	private final static int K=0;
    /**
     * 处理截止到上报日期，已经实际结清、垫付结清、正常还款的数据，不上报截止上报日处于逾期状态的数据 (2018-12-20 v)
     * @param context
     * @param map
     * @throws InterruptedException 
     * @throws IOException 
     */
	public static void act_payoff(Context context,List<Map<String,String>> list_map) throws IOException, InterruptedException{
		double act_repay_amt=0;
		String target_repayment_date="";
		String target_repayment_date_k="";
		String payoff_date="";
		int term_no=0;
		String next_target_repayment_date_k=null;
		int first=0;
		String min_date="";
		for(Map<String,String> map:list_map){ 
			 
			try{
			payoff_date=BHZXUtils.time_to_date(map.get("payoff_time")); 
			target_repayment_date=BHZXUtils.time_to_date(map.get("target_repayment_date"));
			target_repayment_date_k=DateUtil.formateDateStr(DateUtil.addDay(DateUtil.formateToDate(target_repayment_date,"yyyy-MM-dd"), K+1),"yyyy-MM-dd");
			if(!map.get("next_due_date").equals("")){
				next_target_repayment_date_k=DateUtil.formateDateStr(DateUtil.addDay(DateUtil.formateToDate(map.get("next_due_date"),"yyyy-MM-dd"), K+1),"yyyy-MM-dd");
			}
			
			act_repay_amt=act_repay_amt+Double.parseDouble(map.get("planned_payment"));
			term_no=Integer.parseInt(map.get("term_no"));
			//提前还款、正常还款的情况
			if(payoff_date.compareTo(target_repayment_date_k)<0){
				context.getCounter("state","normal.records").increment(1);
				min_date="";
				process_normal(context,list_map,map.get("payoff_time"),term_no,term_no);
				
			}else{
				context.getCounter("state","overdue.records").increment(1);
				//逾期情况
				//如果连续多期实际还款时间相同，则属于一次还款(不包含部分提前还清),用本次还款最后一期作为上报期数
				if(min_date.equals("")){
					min_date=map.get("target_repayment_date");
				}
				if(payoff_date.equals(BHZXUtils.time_to_date(map.get("next_payoff_time")))
						&& BHZXUtils.time_to_date(map.get("next_payoff_time")).compareTo(next_target_repayment_date_k)>=0){
					continue;
				}
				process_overdue(context,list_map,min_date,map.get("payoff_time"),term_no);
			}
			
			}catch(Exception e){
				System.out.println("-------------------"+map.get("next_payoff_time"));
				context.getCounter("error","act_payoff.err").increment(1);
				throw e;
		}  
		}
	}
	private static void process_overdue(Context context,List<Map<String,String>> list_maps,String min_date,String act_payoff_time,int act_term_no) throws IOException, InterruptedException{
		double arr[]=null;
		String target_repayment_date="";
		String next_target_repayment_date_k=null;
		int term_no=0;
		String act_payoff_date=BHZXUtils.time_to_date(act_payoff_time);
		int old_days=0;
		String uploadTs=DateUtil.getCurrentDateTime();
		
		for(Map<String,String> map :list_maps){
			target_repayment_date=BHZXUtils.time_to_date(map.get("target_repayment_date"));
			next_target_repayment_date_k=DateUtil.formateDateStr(DateUtil.addDay(DateUtil.formateToDate(map.get("next_due_date"),"yyyy-MM-dd"), K+1),"yyyy-MM-dd");
			
			//根据还款时间，判定本次还款进件所在期数
			if(act_payoff_date.compareTo(target_repayment_date)>=0 && act_payoff_date.compareTo(next_target_repayment_date_k)<0){
				term_no=Integer.parseInt(map.get("term_no"));
				if(min_date.equals("")){
					old_days=0;
				}else{
					old_days=DateUtil.date_diff(act_payoff_date, min_date);
				}
				
				arr = getLoan_due_amt(list_maps, term_no, act_term_no, act_payoff_date);
				map.put("uploadTs", uploadTs);
				map.put("target_repayment", String.valueOf(arr[0]));
				map.put("remaining_amount", String.valueOf(arr[1]));
				map.put("real_repayment", String.valueOf(arr[2]));
				map.put("overdue_amount", String.valueOf(arr[3])); //当 前 逾期总额 
				map.put("term_status",old_days>0?"overdue":"normal");
				map.put("real_repayment_date",act_payoff_time); //实际还款时间
				map.put("overdue_status",old_days>0?"D"+old_days:"");
				map.put("status_confirm_at",act_payoff_time);
				map.put("overdue_amount", String.valueOf(0)); //当 前 逾期总额
				map.put("req_id", MD5Util.getMd5(map.get("repay_plan_key")+map.get("status_confirm_at")+map.get("term_status"))); 
				if(term_no==Integer.parseInt(map.get("last_period")) && old_days<=0){
					map.put("loan_status", "3");
				}else if(old_days<=0) {
					map.put("loan_status", "1");
				}else{
					map.put("loan_status", "2");
				};
				
				val_Text.set(BHZXUtils.processToString(map));
				context.write(key_null, val_Text);
			    break;	
			}
			
		}
	}
	 
	private static void process_normal(Context context,List<Map<String,String>> list_maps,String act_payoff_time,int term_no,int act_term_no) throws IOException, InterruptedException{
		double arr[]=null;
		 
		String act_payoff_date=BHZXUtils.time_to_date(act_payoff_time);
		String uploadTs=DateUtil.getCurrentDateTime();
		int old_days=0;
		for(Map<String,String> map :list_maps){
			//根据还款时间，判定本次还款进件所在期数
			if(term_no==Integer.parseInt(map.get("term_no"))){
				old_days=DateUtil.date_diff(act_payoff_date, map.get("target_repayment_date"));
				arr = getLoan_due_amt(list_maps, term_no, act_term_no, act_payoff_date);
				map.put("uploadTs", uploadTs);
				map.put("target_repayment", String.valueOf(arr[0]));
				map.put("remaining_amount", String.valueOf(arr[1]));
				map.put("real_repayment", String.valueOf(arr[2]));
				map.put("overdue_amount", String.valueOf(arr[3])); //当 前 逾期总额 
				map.put("term_status",old_days>0?"overdue":"normal");
				map.put("real_repayment_date",act_payoff_time); //实际还款时间
				map.put("overdue_status",old_days>0?"D"+old_days:"");
				map.put("status_confirm_at",act_payoff_time);
				map.put("req_id", MD5Util.getMd5(map.get("repay_plan_key")+map.get("status_confirm_at")+map.get("term_status"))); 
				if(act_term_no==Integer.parseInt(map.get("last_period")) && old_days<=0){
					map.put("loan_status", "3");
				}else if(old_days<=0) {
					map.put("loan_status", "1");
				}else{
					map.put("loan_status", "2");
				};
				val_Text.set(BHZXUtils.processToString(map));
				context.write(key_null, val_Text);
			    break;	
			}
			
		}
	}
	//计算当期剩余应还款金额、借款剩余余额、本次实际还款金额
		private static double[] getLoan_due_amt(List<Map<String,String>> list_maps,int term_no,int act_term_no,String act_payoff_date){
				double loan_due_amt=0;
				String payoff_date="";
				double remain_amt=0;
				double[] arr=new double[4];
				double act_amount=0;
				double overdue_amount=0;
				for(Map<String,String> m :list_maps){
					payoff_date=BHZXUtils.time_to_date(m.get("payoff_time"));
					if(Integer.parseInt(m.get("term_no"))<=term_no && !m.get("is_true").equals("true")){
						loan_due_amt=loan_due_amt+Double.parseDouble(m.get("planned_payment"));;
						
					}
					if(payoff_date.equals(act_payoff_date) && Integer.parseInt(m.get("term_no"))<=act_term_no){
						act_amount=act_amount+Double.parseDouble(m.get("planned_payment"));
						m.put("is_true", "true");
					}
					if(!m.get("is_true").equals("true")){
						remain_amt=remain_amt+Double.parseDouble(m.get("planned_payment"));
					}
					if(Integer.parseInt(m.get("term_no"))<=term_no && !m.get("is_true").equals("true")){
						overdue_amount=overdue_amount+Double.parseDouble(m.get("planned_payment"));;
						
					}
					
	             }
				arr[0]=loan_due_amt;
				arr[1]=remain_amt;
				arr[2]=act_amount;
				arr[3]=overdue_amount;
				return arr;
			}
		 
		
}
